package com.github.caijh.mall.system.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.Resource;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.caijh.framework.data.redis.Redis;
import com.github.caijh.mall.constants.Constants;
import com.github.caijh.mall.system.dao.SystemCityDao;
import com.github.caijh.mall.system.model.SystemCity;
import com.github.caijh.mall.system.service.SystemCityAsyncService;
import com.github.caijh.mall.system.vo.SystemCityTreeVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class SystemCityAsyncServiceImpl extends ServiceImpl<SystemCityDao, SystemCity> implements SystemCityAsyncService {

    @Resource
    private SystemCityDao dao;

    @Autowired
    private Redis redis;

    /**
     * @return {@code List<SystemCityTreeVo>}
     */
    @Override
    public List<SystemCityTreeVo> cityTree() {

        LambdaQueryWrapper<SystemCity> wrapper = Wrappers.<SystemCity>lambdaQuery()
                .select(SystemCity::getCityId, SystemCity::getParentId, SystemCity::getName)
                .eq(SystemCity::getIsShow, true);
        List<SystemCity> allCities = dao.selectList(wrapper);

        if (allCities == null) {
            return Collections.emptyList();
        }

        List<SystemCityTreeVo> treeList = allCities.stream()
                                                   .map(e -> {
                                                       SystemCityTreeVo systemCityTreeVo = new SystemCityTreeVo();
                                                       BeanUtils.copyProperties(e, systemCityTreeVo);
                                                       return systemCityTreeVo;
                                                   }).collect(Collectors.toList());

        Map<Integer, SystemCityTreeVo> map = treeList.stream().collect(Collectors
                .toMap(SystemCityTreeVo::getCityId, systemCityTreeVo1 -> systemCityTreeVo1));

        List<SystemCityTreeVo> tree = new ArrayList<>();
        for (SystemCityTreeVo vo : treeList) {
            SystemCityTreeVo parent = map.get(vo.getParentId());
            if (parent != null) {
                parent.getChild().add(vo);
            } else {
                tree.add(vo);
            }
        }

        redis.set(Constants.CITY_LIST_TREE, tree, Redis.Expired.NOT_EXPIRED);

        return tree;
    }

}

